#!/usr/bin/env python
#
#       Outgoing.py
#       
#       Copyright 2009 Ben Davis <its.hip@gmail.com>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.

import Interfaces, Effects

class Packet:
    """Base-class for packets. Simply put in the info you need to send
    and create a matching class in the Server Outgoing.py which acts upon
    the data on a __call__"""
    def __call__(self):
        pass

class AddPlayer(Packet):
    """Add a player to the game"""
    def __call__(self, entities):
        entities.players[self.player.key()] = self.player
        entities.interface.append(Interfaces.TimedBox(entities.interface, self.player.name + " entered the game."))

class AddShip(Packet):
    """Add a ship to player"""
    def __call__(self, entities):
        self.entities.players[self.player].ships[self.ship.key()] = self.ship

class Fire(Packet):
    def __call__(self, entities):
        # For now, just damage ships instantly
        # Loop through all the ships damaged
        for ship, player, damage in self.damaged:
            target = entities.players[player].ships[ship]
            # bop the target about a bit.
            target.xy_mod.push(entities.players[self.player].ships[self.ship].weapons[self.weapon].recoil, target.get_direction_to_tile_2(entities.players[self.player].ships[self.ship].x, entities.players[self.player].ships[self.ship].y) + 4)
            # Take away the damage from health
            target.health -= damage
            target.hit()
            entities.effects.add_higher(Effects.FloatyText(entities, (255, 0, 0), "-" + str(damage), target))
            # If ship has no health left
            if target.health <= 0:
                # Destroy it
                target.hit_critical()
                target.die()
                del(entities.players[player].ships[ship])
                # If this is client's selected ship
                if entities.selected == target:
                    # Select nothing
                    entities.selected = None
        ship = entities.players[self.player].ships[self.ship]
        ship.steam -= ship.weapons[self.weapon].steam
        ship.fire(self.weapon)
        

class Message(Packet):
    def __call__(self, entities):
        entities.interface.append(Interfaces.TimedBox(entities.interface, self.message))

class NewTurn(Packet):
    def __call__(self, entities):
        entities.players.turn = self.player
        for ship in entities.players[entities.players.turn].ships.values():
            ship.steam += ship.steam_prod
            if ship.steam > ship.steam_max:
                ship.steam = ship.steam_max

class Orders(Packet):
    def __call__(self, entities):
        # Find the ship which has orders
        ship = entities.players[self.player].ships[self.ship]
        # Point the orders to the ship
        for order in self.orders:
            order.ship = ship
        # Point the ship to the orders
        ship.orders = self.orders
        
class RemovePlayer(Packet):
    """Remove a player from the game"""
    def __call__(self, entities):
        entities.interface.append(Interfaces.TimedBox(entities.interface, entities.players[self.player].name + " left the game."))
        if entities.selected in entities.players[self.player].ships.values():
            entities.selected = None
        del(entities.players[self.player])
    
class Said(Packet):
    """Create a text box with whatever a player has said"""
    def __call__(self, entities):
        entities.interface.append(Interfaces.TimedBox(entities.interface, entities.players[self.player].name + ": " + self.text))

class Sync(Packet):
    """Send all players and the map"""
    def __call__(self, entities):
        entities.players = self.players
        entities.players.entities = entities
        entities.player = entities.players[self.player]
        entities.players.__setup__()
        entities.map = self.map
        entities.map.__setup__(entities)
